package fr.resasante.ejb.service.helper;

import java.util.Locale;

import javax.naming.NamingException;

import org.hibernate.Criteria;
import org.hibernate.Hibernate;
import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;
import org.jboss.logging.Logger;

import fr.resasante.ejb.dto.User;
import fr.resasante.ejb.util.HibernateUtil;
import fr.resasante.ejb.utils.EjbResponse;

/**
 * Class for getting system properties
 * 
 * @author GEFFROY-DE-VILLEBLAN
 * 
 */
public final class UserViewHelper {
	/**
	 * class instance
	 */
	private static volatile UserViewHelper instance = null;

	/**
	 * Logger for the class
	 */
	private static final Logger logger = Logger.getLogger(UserViewHelper.class.getName());

	/**
	 * Method returning a Singleton class instance
	 * 
	 * @return Singleton instance
	 * @throws NamingException
	 */
	public final static UserViewHelper getInstance() {
		if (UserViewHelper.instance == null) {
			synchronized (UserViewHelper.class) {
				if (UserViewHelper.instance == null) {
					UserViewHelper.instance = new UserViewHelper();
				}
			}
		}
		return UserViewHelper.instance;
	}

	/**
	 * EJb response
	 */
	private EjbResponse ejbResponse = null;

	/**
	 * Constructor
	 */
	private UserViewHelper() {
		super();
	}

	/**
	 * Check if an email exists
	 * 
	 * @param email
	 *            The email
	 * @return true if the email exists, false otherwise
	 */
	public boolean emailExists(String email) {
		logger.info("Looking for user having email " + email);
		final Session session = HibernateUtil.getSession();
		final Criteria criteria = session.createCriteria(User.class);
		criteria.add(Restrictions.eq("mail", email));
		final User user = (User) criteria.uniqueResult();
		session.close();
		if (user == null) {
			return false;
		}
		return true;
	}

	/**
	 * Get an user by its email
	 * 
	 * @param mail
	 *            The user email
	 * @return The User object
	 */
	private User getUserByMail(String mail) {
		logger.info("Looking for user having mail " + mail);
		final Session session = HibernateUtil.getSession();
		final Criteria criteria = session.createCriteria(User.class);
		criteria.add(Restrictions.eq("mail", mail));
		final User foundUser = (User) criteria.uniqueResult();
		session.close();
		if (null == foundUser) {
			logger.info("Unkown user having mail " + mail);
		} else {
			logger.info("The user having mail " + mail + " has been found");
		}
		return foundUser;
	}

	/**
	 * Get a user by its salt
	 * 
	 * @param username
	 *            The salt
	 * @param enabled
	 *            If the user must be enabled
	 * @return the user object
	 */
	public User getUserBySalt(String salt, boolean enabled) {
		logger.info("Looking for user having salt " + salt);
		final Session session = HibernateUtil.getSession();
		final Criteria criteria = session.createCriteria(User.class);
		criteria.add(Restrictions.eq("salt", salt));
		criteria.add(Restrictions.eq("enabled", enabled));
		final User user = (User) criteria.uniqueResult();
		if (user != null) {
			Hibernate.initialize(user.getUserRoles());
		}
		session.close();
		return user;
	}

	/**
	 * Get a user by its username
	 * 
	 * @param username
	 *            The username
	 * @return the user object
	 */
	public User getUserByUsername(String username) {
		logger.info("Looking for user having username " + username);
		final Session session = HibernateUtil.getSession();
		final Criteria criteria = session.createCriteria(User.class);
		criteria.add(Restrictions.eq("username", username));
		criteria.add(Restrictions.eq("enabled", true));
		final User user = (User) criteria.uniqueResult();
		if (user != null) {
			Hibernate.initialize(user.getUserRoles());
		}
		session.close();
		return user;
	}

	/**
	 * Retrieve an account with email
	 * 
	 * @param mail
	 *            The user email
	 * @param The
	 *            locale
	 * @return the user object
	 */
	public EjbResponse retrieveAccount(String mail, Locale locale) {
		ejbResponse = new EjbResponse();
		final User user = getUserByMail(mail);
		if (null != user) {
			if (user.isEnabled()) {
				EmailHelper.getInstance().sendRetrieveAccountEmail(user, locale);
				return ejbResponse;
			} else {
				ejbResponse.addError("error.inactive.account");
				EmailHelper.getInstance().sendConfirmationAccountEmail(user, locale);
			}
		} else {
			ejbResponse.addError("error.mail.unknown");
		}
		return ejbResponse;
	}

	/**
	 * Check if a username exists
	 * 
	 * @param username
	 *            The username
	 * @return true if the username exists, false otherwise
	 */
	public boolean usernameExists(String username) {
		logger.info("Looking for user having username " + username);
		final Session session = HibernateUtil.getSession();
		final Criteria criteria = session.createCriteria(User.class);
		criteria.add(Restrictions.eq("username", username));
		final User user = (User) criteria.uniqueResult();
		session.close();
		if (user == null) {
			return false;
		}
		return true;
	}
}